iT邦幫忙

2026 iThome 鐵人賽

DAY 5
0
ChatGPT & Codex

我的音樂不該被平台綁架:30 天用 ChatGPT × Codex 打造跨平台 Music Recap系列 第 5

Day 5|第一份自己的 YouTube Music Recap:把 15,403 筆活動變成排行

  • 分享至 

  • xImage
  •  

前一天,我替 Music Recap 的數字訂好了規則:活動次數可以計算,未知播放時間保留空值,每個結果都要交代用了多少資料。

今天終於可以打開第一份用自己資料產生的 Recap。

這份報告讀入我的 YouTube Music 活動紀錄,列出來源 ID 活動排行、頻道活動排行,以及日期、月份與時段分布。每張表都附上統計依據、資料覆蓋率和份額分母,讓數字能對回原本的資料。

同一份原始資料,今天開始產生可閱讀的結果

這次使用先前已驗證的 Google Takeout 原始 HTML。執行前先比對檔案,確認與前兩天使用的是同一份資料,再讓它經過匯入器與今天的 Recap 程式。

原檔包含 26,900 張活動卡片。其中 15,403 筆屬於 YouTube Music,另外 11,497 筆一般 YouTube 活動依既有分類規則略過,拒絕與待分類的卡片都是 0。

這 15,403 筆音樂活動,現在產生了以下結果:

項目 真實資料結果
YouTube Music 活動 15,403 筆
不同來源 Video ID 1,197 個
可用頻道標籤 409 組
來源 ID 排行覆蓋率 15,403/15,403,100%
頻道排行覆蓋率 15,376/15,403,99.82%
日期、月份與時段統計覆蓋率 15,403/15,403,100%
實際出現活動的日期 198 天
逐筆播放時間未知 15,403/15,403

這裡的覆蓋率,分母都是這次輸入的音樂活動。100% 代表這批紀錄都能參與該項統計,不能據此推論帳號的全部收聽歷史都已取得。

第一份排行,先回答來源項目出現幾次

來源 ID 排行以 Video ID 分組。同一個 Video ID 出現在多少筆活動裡,就累積多少次。

這批資料的第一名來源項目有 106 次活動,占 15,403 筆可納入活動的約 0.69%。前十列來源項目合計 1,017 次,占約 6.60%;其他來源項目合計 14,386 次。

這些數字描述的是匯出紀錄中的活動次數。106 次活動無法直接換成完整播放 106 次,也無法推算播放分鐘數。

有 Video ID、卻缺少可用標題的紀錄,仍能參與排行。報告會顯示「標題未知」,不會因為名稱缺失而丟掉它。若同一個 Video ID 有多種原始標題,程式使用最常出現的可用標題作為顯示名稱。

另一方面,兩個 Video ID 即使標題相同,目前仍分開保留。不同版本是否代表同一首歌曲,要等後面的歌曲身分辨識處理。這也是報告目前使用「來源 ID 活動排行」這個名稱的原因。

次數相同時,報告會保留並列名次,並以來源 ID 穩定排序。重跑同一批事件,結果不會因為輸入順序而換位置。

頻道排行的份額,分母是 15,376

這批音樂活動並非每筆都有可用頻道名稱。

原始頻道缺值共有 114 筆。既有匯入器利用相同 Video ID 的唯一頻道證據補回 87 筆,剩下 27 筆仍保留未知。因此,頻道排行能使用的活動數是 15,376 筆。

這時,排行裡有兩個需要分開的比例。

第一個是某個頻道的活動份額。這次第一名頻道標籤累積 6,116 筆活動,所以它在可納入頻道排行的活動中占:

6,116 ÷ 15,376 ≈ 39.78%

第二個是整份頻道排行的資料覆蓋率:

15,376 ÷ 15,403 ≈ 99.82%

39.78% 描述該頻道在榜內的份額;99.82% 描述這張榜使用了多少輸入資料。兩個分母回答的問題不同,所以程式分開保存。

只顯示前十名時,也不會把前十名的份額重新湊成 100%。這次頻道榜前十列合計 13,559 筆,約占可納入活動的 88.18%;其他可用頻道合計 1,817 筆。另外 27 筆頻道缺值則清楚列為未納入。

目前的頻道分組沿用來源中的精確標籤。帶有 Topic 的名稱與一般頻道名稱會分開,尚未把它們歸成同一位歌手。

我的活動落在哪些月份?

時間分布沿用這份匯出的明確解析設定:把來源中的 CST 解釋為 +08:00,報表也使用 +08:00。

在這個設定下,這批音樂活動的首末時間是 2026 年 1 月 31 日 22:33:30 到 9 月 15 日 18:52:27。

月份分布如下。統計依據都是活動次數,每列份額的分母為 15,403 筆,時間欄位覆蓋率為 100%。

月份 活動數
2026 年 1 月 21
2026 年 2 月 2,472
2026 年 3 月 1,997
2026 年 4 月 1,539
2026 年 5 月 1,336
2026 年 6 月 1,119
2026 年 7 月 3,454
2026 年 8 月 2,139
2026 年 9 月 1,326

在這份資料裡,7 月的活動最多,約占全部音樂活動的 22.42%。1 月與 9 月只包含這批資料首末端的部分日期,因此不能把它們當成完整月份,直接解讀為聆聽量下降。

每小時分布也已產生。其中 00:00 到 00:59 累積 1,278 筆活動,約占 8.30%,是這批資料中活動最多的一個小時區間。

這表示紀錄中的事件集中在哪些時段,還不能推論每個時段實際播放了多久。日期分布列出有活動的 198 天,沒有紀錄的日期也不會被直接解釋成完全沒聽音樂。

秒數未知,報告仍然能交代清楚

這次所有 YouTube Music 事件的 played_ms 都維持 null

所以,逐筆觀測播放時間與完整觀測播放時間都標示為無法提供。程式沒有用歌曲長度,也沒有用兩筆事件的間隔去填補秒數。

另外提供的官方 Recap 總分鐘數目前也尚未取得,這個欄位同樣保留無法提供。之後取得時,會保存它自己的期間,不分攤到每筆事件。

活動報告仍然能回答來源項目、頻道和時間分布的問題,同時讓缺少的資料留在讀者看得到的位置。

這次怎麼確認報告真的正確?

我沒有只停在程式成功輸出檔案。

第一層驗收從同一份原始 HTML 開始,經過嚴格匯入,再讓全部 15,403 筆真實事件進入 Recap。驗收腳本的 14 項檢查全數通過,包括事件數、來源 ID 數量、欄位覆蓋率、首末時間、未知時長與各表加總。

第二層另外使用不同的 HTML 解析方式讀取原始檔,重新計算來源分類、Video ID、可用頻道、日期、月份和小時分布,再與新報告對照。

這次獨立核對涵蓋來源與頻道榜各十列、全部 198 個日期分組、9 個月份與 24 個小時分組,也核對各表完整組數、可用活動總數、份額與被省略的活動數。30 項核對全部相符。

先前同一版功能已通過合成資料端到端流程與既有回歸測試;這次補上的,則是原先缺少的真實 Recap 執行證據。

ChatGPT 今天做了什麼?

今天由 ChatGPT 接續前一天的 metric contract,把排行、份額、coverage 與時間分布真正接到 Recap 輸出。

過程中也檢查了幾個很容易讓結果看起來合理、實際卻算錯的地方。

例如只顯示前十名時,不能把前十名重新湊成 100%;頻道缺值不能直接忽略分母差異;Video ID 名稱相似也不能直接合併;時間分布還要先套用正確的時區解釋。

最後再用真實原始檔重新跑完整流程,並透過另一套解析方式重新計算統計數字,確認新產生的 Recap 與原始資料一致。

這次沒有另外啟動 Codex 工作任務。程式、測試與驗收文件持續保存在專案裡,之後 ChatGPT 與 Codex 都能依同一份狀態接手。

第一份 Recap 已經能打開了

今天完成的成果,是從我的真實 YouTube Music 原始資料產生一份可以閱讀的活動報告。

目前已經可以看到來源 ID 活動排行、頻道活動排行、月份分布、日期分布與每小時活動分布,而且每一項結果都保留統計依據和資料覆蓋率。

雖然 YouTube Music Takeout 沒有提供每筆實際播放秒數,但至少現在這 15,403 筆活動已經真正開始變成一份屬於自己的 Music Recap。

下一天將接上第二個必要資料來源:Spotify。

我要先檢查真實 Spotify 匯出檔到底提供哪些欄位、它的時間代表什麼,以及 msPlayed 是否真的能讓我們補上 YouTube Music 缺少的播放時間資訊。


上一篇
Day 4|YouTube Music 沒有播放秒數,那 Recap 還能算什麼?
系列文
我的音樂不該被平台綁架:30 天用 ChatGPT × Codex 打造跨平台 Music Recap5
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
lin1015
iT邦新手 5 級 ‧ 2026-09-19 18:32:12

把榜內份額與資料覆蓋率分開,還特別標出 1 月、9 月是部分月份,這讓 Recap 不會把漂亮數字講過頭。接上 Spotify 後,跨平台同曲辨識會怎麼驗收?你會優先用 ISRC,還是名稱、藝人與時長的組合規則?

我要留言

立即登入留言